package com.hsgene.pay.service.impl;

import com.hsgene.common.util.basic.JsonUtils;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.order.constants.PayType;
import com.hsgene.order.constants.v1.OrderStatus;
import com.hsgene.order.constants.v1.PaymentBusinessType;
import com.hsgene.order.constants.v1.PaymentIntStatus;
import com.hsgene.order.domain.v1.GeneticTestingOrder;
import com.hsgene.order.domain.v1.GeneticTestingOrderInterchange;
import com.hsgene.order.domain.v1.GeneticTestingOrderPayment;
import com.hsgene.order.exception.OrderErrorCode;
import com.hsgene.pay.exception.PayErrorCode;
import com.hsgene.pay.persistence.OrderPaymentRepository;
import com.hsgene.pay.service.GeneticPaymentService;
import com.hsgene.pay.service.OrderPayService;
import com.hsgene.pay.service.api.OrderInternalApiService;
import com.hsgene.pay.service.support.QrCodeSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map;

/**
 * 支付ServiceImpl
 *
 * @author wangbing
 * @version 1.0, 2018/10/9
 */
@Service
public class GeneticPaymentServiceImpl implements GeneticPaymentService {

    private static final Logger LOGGER = LoggerFactory.getLogger(GeneticPaymentServiceImpl.class);

    @Resource
    private OrderPaymentRepository orderPaymentRepository;

    @Resource
    private OrderInternalApiService orderInternalApiService;

    @Resource
    private OrderPayService orderPayService;

    @Override
    public ApiResult getPayment(String paymentId, HttpServletResponse response) {
        GeneticTestingOrderPayment payment = orderPaymentRepository.findById(paymentId);
        if (payment == null || payment.getDeleteFlag() == 1) {
            return ApiResult.fail(PayErrorCode.GENETIC_TESTING_ORDER_PAYMENT_NOT_EXISTED);
        }
        PaymentIntStatus paymentIntStatus = PaymentIntStatus.getEnum(payment.getPaymentStatus());
        if (PaymentIntStatus.PAID.equals(paymentIntStatus)) {
            return ApiResult.fail(PayErrorCode.GENETIC_TESTING_ORDER_PAYMENT_PAID);
        }

        PaymentBusinessType businessType = PaymentBusinessType.getEnum(payment.getBusinessType());
        if (PaymentBusinessType.UNDEFINED.equals(businessType)) {
            return ApiResult.fail(PayErrorCode.GENETIC_TESTING_ORDER_PAYMENT_BUSINESS_TYPE);
        }
        if (PaymentBusinessType.GENETIC_TESTING.equals(businessType)) {
            return payGeneticTestingOrder(payment);
        } else {
            return payGeneticTestingAddition(payment, response);
        }
    }

    /**
     * 正常订单支付处理
     *
     * @param payment 支付信息
     * @return 支付处理
     */
    private ApiResult<Map<String, Object>> payGeneticTestingOrder(GeneticTestingOrderPayment payment) {
        PayType payType = PayType.getEnum(payment.getPaymentWay());
        int payAmount = payment.getPaymentAmount().multiply(new BigDecimal(100)).intValue();
        ApiResult<GeneticTestingOrder> orderApiResult = orderInternalApiService.getTestingOrder(payment.getBusinessId());
        if (!orderApiResult.isSucc()) {
            return ApiResult.fail(orderApiResult.getError());
        }
        GeneticTestingOrder order = orderApiResult.getData();
        if (order == null || order.getDeleteFlag() == 1) {
            return ApiResult.fail(OrderErrorCode.ORDER_NOT_EXISTED);
        }
        OrderStatus orderStatus = OrderStatus.getEnum(order.getStatus());
        if (!orderStatus.canPayOnline()) {
            return ApiResult.fail(OrderErrorCode.ORDER_STATUS_EXCEPTION);
        }
        if (!order.getTotalCharges().equals(payment.getPaymentAmount())) {
            return ApiResult.fail(PayErrorCode.PAYMENT_AMOUNT_EXCEPTION);
        }
        ApiResult<Map<String, Object>> payResult = orderPayService.orderPay(payment.getBusinessId(), payType.getCode(), payAmount, PaymentBusinessType.GENETIC_TESTING);
        if (!payResult.isSucc()) {
            return payResult;
        }
        Map<String, Object> paymentInfo = payResult.getData();
        if (CollectionUtils.isEmpty(paymentInfo) || !"SUCCESS".equals(paymentInfo.get("retCode"))) {
            LOGGER.error("支付请求失败：" + JsonUtils.objectToJson(paymentInfo));
            return ApiResult.fail(PayErrorCode.PAYMENT_FAILED);
        }
        String paymentNo = (String) paymentInfo.get("payOrderId");
        payment.setPaymentNo(paymentNo);
        payment.setPaymentStatus(1);
        orderPaymentRepository.update(payment);

        Object o = paymentInfo.get("payParams");
        if (PayType.WX_APP.equals(payType)) {
            paymentInfo.remove("payParams");
            paymentInfo.put("wxPayParams", o);
        } else if (PayType.ALIPAY_MOBILE.equals(payType)) {
            paymentInfo.remove("payParams");
            paymentInfo.put("zfbPayParams", o);
        }
        return ApiResult.succ(paymentInfo);
    }

    /**
     * 补款支付处理
     *
     * @param payment  支付信息
     * @param response HttpServletResponse
     * @return 支付处理
     */
    private ApiResult payGeneticTestingAddition(GeneticTestingOrderPayment payment, HttpServletResponse response) {
        ApiResult<GeneticTestingOrderInterchange> interchangeResult = orderInternalApiService.getTestingOrderInterchange(payment.getBusinessId());
        if (!interchangeResult.isSucc()) {
            return ApiResult.fail(interchangeResult.getError());
        }
        GeneticTestingOrderInterchange interchange = interchangeResult.getData();
        if (interchange == null || interchange.getDeleteFlag() == 1) {
            return ApiResult.fail(OrderErrorCode.ORDER_INTERCHANGE_NOT_EXISTED);
        }
        /*if (!Integer.valueOf(1).equals(interchange.getReplenishmentFlag()) || Integer.valueOf(2).equals(interchange.getStatus())) {
            return ApiResult.fail(OrderErrorCode.ORDER_INTERCHANGE_REPAID_NO_NEED);
        }*/
        PayType payType = PayType.getEnum(payment.getPaymentWay());
        int payAmount = payment.getPaymentAmount().multiply(new BigDecimal(100)).intValue();
        ApiResult<Map<String, Object>> payResult = orderPayService.orderPay(payment.getBusinessId(), payType.getCode(), payAmount, PaymentBusinessType.GENETIC_TESTING_ADDITION);
        if (!payResult.isSucc()) {
            return payResult;
        }
        Map<String, Object> paymentInfo = payResult.getData();
        if (CollectionUtils.isEmpty(paymentInfo) || !"SUCCESS".equals(paymentInfo.get("retCode"))) {
            LOGGER.error("支付请求失败：" + JsonUtils.objectToJson(paymentInfo));
            return ApiResult.fail(PayErrorCode.PAYMENT_FAILED);
        }
        String paymentNo = (String) paymentInfo.get("payOrderId");
        payment.setPaymentNo(paymentNo);
        payment.setPaymentStatus(1);
        orderPaymentRepository.update(payment);

        try {
            return QrCodeSupport.getPayCode(response, paymentInfo);
        } catch (IOException e) {
            LOGGER.error("pay order info is error", e);
            return ApiResult.fail(PayErrorCode.ORDER_PAY_IS_ERROR);
        }

    }
}
